package com.gimi.cloud.jimi.common.utils;

import com.gimi.cloud.jimi.common.utils.lianlian.HttpClientFactory;
import org.apache.commons.codec.CharEncoding;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.*;


/**
 * Http操作工具类
 * @author wbj
 */
public class HttpClientUtil {
	/**
	 * 发送get请求
	 * @param url 请求地址
	 * @param charset 获取结果编码 默认utf8
	 * @return 请求结果
	 * @throws IOException 
	 * @throws UnsupportedEncodingException 
	*/
	public static String sendGet(String url,String charset ) throws Exception {
		String result = "";
		BufferedReader in = null;
		try {
			if(null ==url || "".equals(url)){
				return "";
			}else{
				url = url.indexOf("?")!=-1?url:url+"?date="+new Date().getTime();
			}
			charset = (null == charset || "".equals(charset))?"utf-8":charset;//默认编码为utf8
			URL realUrl = new URL(url);
			URLConnection connection = realUrl.openConnection();// 打开和URL之间的连接
			connection.setRequestProperty("accept", "*/*");// 设置通用的请求属性
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			connection.setReadTimeout(1000);
			connection.connect();// 建立实际的连接
			in = new BufferedReader(new InputStreamReader(connection.getInputStream(), charset));// 定义 BufferedReader输入流来读取URL的响应

			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} finally {
			if (in != null)  in.close();//关闭输入流
		}
		return result;
	}
	
	/**
	 * 发送Get请求
	 * @param url 请求地址
	 * @param params 请求参数
	 * @param header 请求头
	 * @param charset 请求编码默认utf8
	 * 请求结果
	 * @throws Exception 
	*/
	public static String sendGet(String url,Map<String,String> params,Map<String,String> header,String charset) throws Exception{
		String result = "";
		BufferedReader in = null;
		try {
			if(null ==url || "".equals(url)){
				return "";
			}else{
				url = url.indexOf("?")!=-1?url:url+"?date="+new Date().getTime();
			}
			charset = (null == charset || "".equals(charset))?"utf-8":charset;//默认编码为utf8
			StringBuffer buffer = new StringBuffer("&");
			if (params != null && !params.isEmpty()) {//组装参数
				for (Map.Entry<String, String> entry : params.entrySet()) {
					if(null != entry.getValue() && !"".equals(entry.getValue()))
						buffer.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue().toString(),charset)).append("&");
				}
			}
			buffer.deleteCharAt(buffer.length() - 1);//截取末尾&
			URL realUrl = new URL(url+buffer.toString());
			URLConnection connection = realUrl.openConnection();// 打开和URL之间的连接
			connection.setRequestProperty("accept", "*/*");// 设置通用的请求属性
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			if(header != null && !header.isEmpty()){
				for(String str:header.keySet()){
					if(!StringUtil.isEmpty(header.get(str))){
						connection.setRequestProperty(str, header.get(str));
					}
				}
			}
			connection.connect();// 建立实际的连接
			in = new BufferedReader(new InputStreamReader(connection.getInputStream(), charset));// 定义 BufferedReader输入流来读取URL的响应
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} finally {
			if (in != null)  in.close();//关闭输入流
		}
		return result;
	}

	/**
	 * POST请求，字符串形式数据
	 * @param url 请求地址
	 * @param param  请求数据
	 * @param charset  编码方式 默认为utf8
	 * @return 请求结果
	 * @throws IOException 
	 */
	public static String sendPostUrl(String url, String param, String charset) throws Exception {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			if(null ==url || "".equals(url)){
				return "";
			}else{
				url = url.indexOf("?")!=-1?url:url+"?date="+new Date().getTime();
			}
			charset = (null == charset || "".equals(charset))?"utf-8":charset;//默认编码为utf8
			URL realUrl = new URL(url);
			URLConnection conn = realUrl.openConnection();// 打开和URL之间的连接
			conn.setRequestProperty("accept", "*/*");// 设置通用的请求属性
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			conn.setDoOutput(true);// 发送POST请求必须设置如下两行
			conn.setDoInput(true);
			out = new PrintWriter(conn.getOutputStream());// 获取URLConnection对象对应的输出流
			out.print(param);// 发送请求参数
			out.flush();// flush输出流的缓冲
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));// 定义BufferedReader输入流来读取URL的响应
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} finally {
			if (out != null)  out.close();//关闭输出流
			if (in != null) in.close();//关闭输入流
		}
		return result;
	}

	/**
	 * POST请求，Map形式数据
	 * @param url 请求地址
	 * @param param 请求数据
	 * @param charset  编码方式 默认为utf8
	 * @return 请求返回结果
	 * @throws IOException 
	 * @throws UnsupportedEncodingException 
	 */
	public static String sendPost(String url, Map<String, String> param, String charset) throws Exception {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";//获取结果
		try {
			if(null ==url || "".equals(url)){
				return "";
			}
			else{
				url = url.indexOf("?")!=-1?url:url+"?date="+new Date().getTime();
			}
			charset = (null == charset || "".equals(charset))?"utf-8":charset;//默认编码为utf8
			StringBuffer buffer = new StringBuffer("&");
			if (param != null && !param.isEmpty()) {//组装参数
				for (Map.Entry<String, String> entry : param.entrySet()) {
					if(null != entry.getValue() && !"".equals(entry.getValue()))
						buffer.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue().toString(),charset)).append("&");
				}
			}
			buffer.deleteCharAt(buffer.length() - 1);//截取末尾&
			URL realUrl = new URL(url);// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();//开始请求
			conn.setRequestProperty("accept", "*/*");// 设置通用的请求属性
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			conn.setDoOutput(true);// 发送POST请求必须设置如下两行
			conn.setDoInput(true);
			out = new PrintWriter(conn.getOutputStream());// 获取URLConnection对象对应的输出流
			out.print(buffer);// 发送请求参数
			out.flush();// flush输出流的缓冲
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));// 定义BufferedReader输入流来读取URL的响应
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		}finally {
			if (out != null) out.close();//关闭输出流
			if (in != null) in.close();//关闭输入流
		}
		return result;
	}


	//-----------------------------------------------------以下方法引用apache的httpclient--------------------------------
	/**
	 * 发送json格式的post请求
	 * @param url 访问地址
	 * @param json 请求参数(json字符串)
	 * @return
	 * @throws ParseException
	 * @throws IOException
	 */
	public static String sendPostJson(String url,String json,Header[] headers) throws ParseException, IOException {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		StringEntity entity = new StringEntity(json, CharEncoding.UTF_8);
		entity.setContentEncoding(CharEncoding.UTF_8);
		entity.setContentType("application/json");
		httpPost.setEntity(entity);
		httpPost.setHeaders(headers);
		httpPost.setHeader("Content-Encoding", CharEncoding.UTF_8);
		httpPost.setHeader("content-type", "application/json");
		CloseableHttpResponse response = httpClient.execute(httpPost);
		return EntityUtils.toString(response.getEntity());
	}

	/**
	 * 发送普通格式参数的post请求
	 */
	public static String sendPostParam(String url,Map<String, String> paramMap,Header[] headers) throws ParseException, IOException {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		List<NameValuePair> params=new ArrayList<NameValuePair>();
		if (paramMap!=null) {
			Set<String> keySet = paramMap.keySet();
			for (String key : keySet) {
				params.add(new BasicNameValuePair(key, paramMap.get(key)));
			}
		}
		httpPost.setEntity(new UrlEncodedFormEntity(params,CharEncoding.UTF_8));
		httpPost.setHeaders(headers);
		CloseableHttpResponse response = httpClient.execute(httpPost);
		return EntityUtils.toString(response.getEntity());
	}

	/**
	 * 发送get请求
	 * @param url 访问地址
	 * @param paramMap 请求参数
	 * @return
	 * @throws ParseException
	 * @throws IOException
	 */
	public static String sendGet(String url,Map<String, String> paramMap) throws ParseException, IOException {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		List<NameValuePair> parameters = new ArrayList<>();
		if (paramMap!=null) {
			Set<String> keySet = paramMap.keySet();
			for (String key : keySet) {
				parameters.add(new BasicNameValuePair(key, paramMap.get(key)));
			}
		}
		String param = URLEncodedUtils.format(parameters, "UTF-8");
		HttpGet httpGet = new HttpGet(url+"?"+param);
		CloseableHttpResponse response = httpClient.execute(httpGet);
		return EntityUtils.toString(response.getEntity());
	}

	public static String doRequestPostString(String reqStr, String uri) {
		HttpClient httpClient = HttpClientFactory.getThreadSafeHttpClient();
		HttpPost httpPost = new HttpPost(StringUtils.trim(uri));
		httpPost.setHeader(HTTP.USER_AGENT, "httpcomponents");
		httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
		httpClient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15000);
		HttpResponse response = null;
		HttpEntity entity = null;
		StringEntity stringEntiry = null;
		try {
			stringEntiry = new StringEntity(reqStr, "utf-8");
			httpPost.setEntity(stringEntiry);
			long start = System.currentTimeMillis();
			response = httpClient.execute(httpPost);
			int status = response.getStatusLine().getStatusCode();
			// 获取响应内容
			String retData = null;
			if (null != response) {
				entity = response.getEntity();
				retData = StringEscapeUtils.unescapeJava(StringUtils.trim(EntityUtils.toString(entity, "utf-8")));
			}
			if (HttpStatus.SC_OK == status) { // 请求成功
				return retData;
			}
		} catch (Exception e) { // 读取响应错误
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			try {
				if (null != stringEntiry)
					EntityUtils.consume(stringEntiry);
				httpPost.abort(); // 释放连接资源
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		return "error";
	}
}
